package com.blork.rag;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONTokener;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class RagEvents {
	
	public static final String url = "http://sheffieldrag.com/events/index/json";

	public Context context;
	private EventsData data;
	private ArrayList<RagEvent> oldEventList;
	private ArrayList<RagEvent> jsonEventList = new ArrayList<RagEvent>();

	private NotificationManager nm;

	private Boolean notificationsEnabled;
	
	public RagEvents(Context context, NotificationManager nm, Boolean notificationsEnabled) throws MalformedURLException, ClassCastException, JSONException, IOException, URISyntaxException, InterruptedException, ParseException{
		this.context = context;
		this.data = new EventsData(this.context);
		this.nm = nm;
		this.notificationsEnabled = notificationsEnabled;
		this.getDetails();
	}
	

	public void getDetails() throws MalformedURLException, JSONException, IOException, URISyntaxException, ClassCastException, InterruptedException, ParseException{
		
		JSONArray events;
		
		String allJson = getJSON(new URL(RagEvents.url));
		
		JSONTokener jsonTokener = new JSONTokener(allJson);
		events = (JSONArray) jsonTokener.nextValue();

		int x = events.length();
		
		oldEventList = RagEvents.oldEvents(data);
		Log.i(Rag.TAG, oldEventList.toString());

		int newEvents = 0;
		String contentTitle = "";
		String tickerText = "";
		String contentText = "";
		
		for(int i = 0; i < x; i++){
			RagEvent event = new RagEvent(events.getJSONObject(i));
			jsonEventList.add(event);
			boolean isNew = true;
			for(RagEvent r : oldEventList){
				if(event.equals(r)){
					isNew = false;
					Log.i(Rag.TAG, event.title+" is an old event.");
					event.update(data);
					if(!event.strictEquals(r)){
						Log.i(Rag.TAG, "event details changed.");
					}
					break;
				}
			}

			if(isNew && event.inFuture()){
				Log.i(Rag.TAG, "new event");
				event.save(data);
				newEvents++;


				if(newEvents == 1){
					tickerText = "New Event: "+event.title;
					contentTitle = event.title+" added.";
					contentText = event.tagline;
				}else{ //Update notification if it already exists rather than annoying user.
					tickerText = "New Events!";
					contentTitle = newEvents+" new events added.";
					contentText = "Read more about them!";
				}
				
			}
		
		}	
		
		
		for(RagEvent r : oldEventList){
			int k = 0;
			for(RagEvent j : jsonEventList){
				if(r.equals(j)){
					k++;
				}
			}
			if(k == 0){
				Log.i(Rag.TAG, "Removing event "+r.title);
				r.delete(data);
			}
		}
		
		int icon = R.drawable.notification;
		
		if(newEvents > 0 && notificationsEnabled){
			Notification notification = new Notification(icon, tickerText, System.currentTimeMillis());
			notification.flags = Notification.FLAG_AUTO_CANCEL;
			Intent notificationIntent = new Intent(this.context, Upcoming.class);
			PendingIntent contentIntent = PendingIntent.getActivity(this.context, 0, notificationIntent, 0);
			notification.setLatestEventInfo(this.context, contentTitle, contentText, contentIntent);
			nm.notify(2, notification);
		}
	}



	private static ArrayList<RagEvent> oldEvents(EventsData data) {
		
		ArrayList<RagEvent> events = new ArrayList<RagEvent>();
		
		SQLiteDatabase db = data.getReadableDatabase();
				
		Cursor cursor = null;
		try {
			cursor = db.query("events", null,
			        null, null, null, null, null);	
			
			cursor.moveToFirst(); 
			do {
				RagEvent event = new RagEvent(cursor);
				events.add(event);
			} while(cursor.moveToNext());
			
		} catch (Exception e) {
			e.printStackTrace();
			return events;
		} finally {
			db.close();
			cursor.close();
		}
		
		return events;
	}

	private String getJSON(URL url) throws IOException, URISyntaxException {
		InputStream instream = RagEvents.getStream(url);
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(instream));
     
        final StringBuilder sb = new StringBuilder();
       
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        
        return sb.toString();
    }
	   
    
    private static InputStream getStream(URL url) throws ClientProtocolException, IOException, OutOfMemoryError{
    	 HttpGet httpRequest = null;

         try {
         	httpRequest = new HttpGet(url.toURI());
         	httpRequest.removeHeaders("User-Agent");
         	httpRequest.setHeader("Accept-Encoding", "gzip");
         	httpRequest.setHeader( "Pragma", "no-cache" );
         	httpRequest.setHeader( "Cache-Control", "no-cache" );
         	httpRequest.setHeader( "Expires", "0" );
         } catch (URISyntaxException e) {
         	e.printStackTrace();
         }

 		HttpClient httpclient = new DefaultHttpClient();
 		HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
 		
 		HttpEntity entity = response.getEntity();
 		BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity); 
 		InputStream instream = bufHttpEntity.getContent();
 		
 		Header contentEncoding = response.getFirstHeader("Content-Encoding");
 		
 		if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
 		    instream = new GZIPInputStream(instream);
 		    Log.d(Rag.TAG, "Gzipped");
 		}
 		
 		return instream;
    }
}



